added samples
[windows-sources.git] / sdk / samples / all in on code / Visual Studio 2008 / CppMailslotServer / CppMailslotServer.cpp
blob1c02c2f47cd515d7c729141132cbca79cd5f5a2e
1 /****************************** Module Header ******************************\
2 Module Name: CppMailslotServer.cpp
3 Project: CppMailslotServer
4 Copyright (c) Microsoft Corporation.
6 Mailslot is a mechanism for one-way inter-process communication in the local
7 machine or across the computers in the intranet. Any clients can store
8 messages in a mailslot. The creator of the slot, i.e. the server, retrieves
9 the messages that are stored there:
11 Client (GENERIC_WRITE) ---> Server (GENERIC_READ)
13 This code sample demonstrates calling CreateMailslot to create a mailslot
14 named "\\.\mailslot\SampleMailslot". The security attributes of the slot are
15 customized to allow Authenticated Users read and write access to the slot,
16 and to allow the Administrators group full access to it. The sample first
17 creates such a mailslot, then it reads and displays new messages in the slot
18 when user presses ENTER in the console.
20 This source is subject to the Microsoft Public License.
21 See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
22 All other rights reserved.
24 THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
25 EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
26 WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
27 \***************************************************************************/
29 #pragma region Includes
30 #include <stdio.h>
31 #include <windows.h>
32 #include <assert.h>
33 #include <sddl.h>
34 #pragma endregion
37 BOOL ReadMailslot(HANDLE hMailslot);
38 BOOL CreateMailslotSecurity(PSECURITY_ATTRIBUTES *ppSa);
39 void FreeMailslotSecurity(PSECURITY_ATTRIBUTES pSa);
42 int wmain(int argc, wchar_t *argv[])
44 // The name of the mailslot. It is in the form of \\.\mailslot\[path]name
45 // The name field must be unique. The name may include multiple levels of
46 // pseudo directories separated by backslashes. For example, both
47 // \\.\mailslot\mailslot_name and \\.\mailslot\abc\def\ghi are valid.
48 const PCWSTR MAILSLOT_NAME = L"\\\\.\\mailslot\\SampleMailslot";
50 DWORD dwError = ERROR_SUCCESS;
51 PSECURITY_ATTRIBUTES pSa = NULL;
52 HANDLE hMailslot = INVALID_HANDLE_VALUE;
54 // Prepare the security attributes (the lpSecurityAttributes parameter in
55 // CreateMailslot) for the mailslot. This is optional. If the
56 // lpSecurityAttributes parameter of CreateMailslot is NULL, the mailslot
57 // gets a default security descriptor and the handle cannot be inherited.
58 // The ACLs in the default security descriptor of a mailslot grant full
59 // control to the LocalSystem account, (elevated) administrators, and the
60 // creator owner. They also give only read access to members of the
61 // Everyone group and the anonymous account. However, if you want to
62 // customize the security permission of the mailslot, (e.g. to allow
63 // Authenticated Users to read from and write to the pipe), you need to
64 // create a SECURITY_ATTRIBUTES structure.
65 if (!CreateMailslotSecurity(&pSa))
67 dwError = GetLastError();
68 wprintf(L"CreateMailslotSecurity failed w/err 0x%08lx\n", dwError);
69 goto Cleanup;
72 // Create the mailslot.
73 hMailslot = CreateMailslot(
74 MAILSLOT_NAME, // The name of the mailslot
75 0, // No maximum message size
76 MAILSLOT_WAIT_FOREVER, // No time-out for operations
77 pSa // Security attributes
80 if (hMailslot == INVALID_HANDLE_VALUE)
82 dwError = GetLastError();
83 wprintf(L"Unable to create mailslot w/err 0x%08lx\n", dwError);
84 goto Cleanup;
87 wprintf(L"The mailslot (%s) is created.\n", MAILSLOT_NAME);
89 // Check messages in the mailslot.
90 wprintf(L"Press ENTER to check new messages or press Q to quit ...");
91 char cmd = getchar();
92 while (cmd != 'Q' && cmd != 'q')
94 if (cmd == '\n')
96 wprintf(L"Checking new messages...\n");
97 ReadMailslot(hMailslot);
99 wprintf(L"Press ENTER to check new messages or press Q to quit ...");
101 cmd = getchar();
104 Cleanup:
105 // Centralized cleanup for all allocated resources.
106 if (pSa != NULL)
108 FreeMailslotSecurity(pSa);
109 pSa = NULL;
111 if (hMailslot != INVALID_HANDLE_VALUE)
113 CloseHandle(hMailslot);
114 hMailslot = INVALID_HANDLE_VALUE;
117 return 0;
122 // FUNCTION: ReadMailslot(HANDLE);
124 // PURPOSE: Read the messages from a mailslot by using the mailslot handle
125 // in a call to the ReadFile function.
127 // PARAMETERS:
128 // * hMailslot - The handle of the mailslot.
130 BOOL ReadMailslot(HANDLE hMailslot)
132 assert(hMailslot != INVALID_HANDLE_VALUE);
134 DWORD cbMessageBytes = 0; // Size of the message in bytes
135 DWORD cbBytesRead = 0; // Number of bytes read from the slot
136 DWORD cMessages = 0; // Number of messages in the mailslot
137 DWORD nMessageId = 0; // Message ID
139 BOOL fSucceeded = FALSE;
141 PWSTR pszBuffer; // A buffer used to store one message
143 // Check for the number of messages in the mailslot.
144 fSucceeded = GetMailslotInfo(
145 hMailslot, // Handle of the mailslot
146 NULL, // No maximum message size
147 &cbMessageBytes, // Size of next message
148 &cMessages, // Number of messages
149 NULL // No read time-out
151 if (!fSucceeded)
153 wprintf(L"GetMailslotInfo failed w/err 0x%08lx\n", GetLastError());
154 return fSucceeded;
157 if (cbMessageBytes == MAILSLOT_NO_MESSAGE)
159 // There are no new messages in the mailslot at present.
160 wprintf(L"No new messages.\n");
161 return fSucceeded;
164 // Retrieve the messages one by one from the mailslot.
165 while (cMessages != 0)
167 nMessageId++;
169 // Allocate the memory for the message based on its size info,
170 // cbMessageBytes, which was retrieved from GetMailslotInfo.
171 pszBuffer = (PWSTR)LocalAlloc(LPTR, cbMessageBytes);
172 if (NULL == pszBuffer)
174 fSucceeded = FALSE;
175 break;
178 // Read from the mailslot.
179 fSucceeded = ReadFile(
180 hMailslot, // Handle of the slot
181 pszBuffer, // Buffer to receive data
182 cbMessageBytes, // Size of buffer in bytes
183 &cbBytesRead, // Number of bytes read
184 NULL // Not overlapped I/O
186 if (!fSucceeded)
188 wprintf(L"ReadFile failed w/err 0x%08lx\n", GetLastError());
189 LocalFree(pszBuffer);
190 break;
193 // Display the message.
194 wprintf(L"Message #%ld: %s\n", nMessageId, pszBuffer);
196 LocalFree(pszBuffer);
198 // Get the current number of un-read messages in the slot. The number
199 // may not equal the initial message number because new messages may
200 // arrive while we are reading the items in the slot.
201 fSucceeded = GetMailslotInfo(
202 hMailslot, // Handle of the mailslot
203 NULL, // No maximum message size
204 &cbMessageBytes, // Size of next message
205 &cMessages, // Number of messages
206 NULL // No read time-out
208 if (!fSucceeded)
210 wprintf(L"GetMailslotInfo failed w/err 0x%08lx\n", GetLastError());
211 break;
215 return fSucceeded;
220 // FUNCTION: CreateMailslotSecurity(PSECURITY_ATTRIBUTES *)
222 // PURPOSE: The CreateMailslotSecurity function creates and initializes a
223 // new SECURITY_ATTRIBUTES structure to allow Authenticated Users read and
224 // write access to a mailslot, and to allow the Administrators group full
225 // access to the mailslot.
227 // PARAMETERS:
228 // * ppSa - output a pointer to a SECURITY_ATTRIBUTES structure that allows
229 // Authenticated Users read and write access to a mailslot, and allows
230 // the Administrators group full access to the mailslot. The structure
231 // must be freed by calling FreeMailslotSecurity.
233 // RETURN VALUE: Returns TRUE if the function succeeds.
235 // EXAMPLE CALL:
237 // PSECURITY_ATTRIBUTES pSa = NULL;
238 // if (CreateMailslotSecurity(&pSa))
239 // {
240 // // Use the security attributes
241 // // ...
243 // FreeMailslotSecurity(pSa);
244 // }
246 BOOL CreateMailslotSecurity(PSECURITY_ATTRIBUTES *ppSa)
248 BOOL fSucceeded = TRUE;
249 DWORD dwError = ERROR_SUCCESS;
251 PSECURITY_DESCRIPTOR pSd = NULL;
252 PSECURITY_ATTRIBUTES pSa = NULL;
254 // Define the SDDL for the security descriptor.
255 PCWSTR szSDDL = L"D:" // Discretionary ACL
256 L"(A;OICI;GRGW;;;AU)" // Allow read/write to authenticated users
257 L"(A;OICI;GA;;;BA)"; // Allow full control to administrators
259 if (!ConvertStringSecurityDescriptorToSecurityDescriptor(szSDDL,
260 SDDL_REVISION_1, &pSd, NULL))
262 fSucceeded = FALSE;
263 dwError = GetLastError();
264 goto Cleanup;
267 // Allocate the memory of SECURITY_ATTRIBUTES.
268 pSa = (PSECURITY_ATTRIBUTES)LocalAlloc(LPTR, sizeof(*pSa));
269 if (pSa == NULL)
271 fSucceeded = FALSE;
272 dwError = GetLastError();
273 goto Cleanup;
276 pSa->nLength = sizeof(*pSa);
277 pSa->lpSecurityDescriptor = pSd;
278 pSa->bInheritHandle = FALSE;
280 *ppSa = pSa;
282 Cleanup:
283 // Clean up the allocated resources if something is wrong.
284 if (!fSucceeded)
286 if (pSd)
288 LocalFree(pSd);
289 pSd = NULL;
291 if (pSa)
293 LocalFree(pSa);
294 pSa = NULL;
297 SetLastError(dwError);
300 return fSucceeded;
305 // FUNCTION: FreeMailslotSecurity(PSECURITY_ATTRIBUTES)
307 // PURPOSE: The FreeMailslotSecurity function frees a SECURITY_ATTRIBUTES
308 // structure that was created by the CreateMailslotSecurity function.
310 // PARAMETERS:
311 // * pSa - pointer to a SECURITY_ATTRIBUTES structure that was created by
312 // the CreateMailslotSecurity function.
314 void FreeMailslotSecurity(PSECURITY_ATTRIBUTES pSa)
316 if (pSa)
318 if (pSa->lpSecurityDescriptor)
320 LocalFree(pSa->lpSecurityDescriptor);
322 LocalFree(pSa);